package com.germinus.telcoblocks.echarts.Click2Dial;

import org.echarts.servlet.sip.JavaToEChartsMachine;
import org.echarts.servlet.sip.EChartsMachineToJava;
import org.echarts.servlet.sip.EChartsSipServlet;
import org.echarts.servlet.sip.NonSipPort;
import org.echarts.servlet.sip.FeatureBoxException;
import org.echarts.TransitionMachine;
import org.echarts.util.UniqueID;



import javax.servlet.sip.SipApplicationSession;

/**
   JavaToEChartsMachine interface class for the MyClick2DialMachine.
 */
public final class JavaToClick2DialEChartsMachine extends JavaToEChartsMachine {

	/**
	   Initiate click-to-dial session specified by bean's fields.  New
	   session will use instance of the machine's {@link
	   Click2DialEChartsMachineToJava} interface returned by {@link
	   EChartsMachineToJava#getInstance(javax.servlet.sip.SipApplicationSession)
	   EChartsMachineToJava.getInstance()}.
	   @param bean specifies parameters required to
	   establish click-to-dial session e.g. first and second party
	   addresses
	   @return interface instance to control the click-to-dial session
	   created by this method
	 */
	public static final JavaToClick2DialEChartsMachine initiate(final Click2DialEChartsBean bean) throws Exception {
		//final SipApplicationSession appSession = EChartsSipServlet.doNonSip(bean);
		SipApplicationSession appSession = EChartsSipServlet.doNonSip(bean);
		return (JavaToClick2DialEChartsMachine) JavaToEChartsMachine.getInstance(appSession);
	}

	/**
	   Initiate click-to-dial session specified by bean's
	   fields. Newly created machine will use specified instance of
	   machine's {@link Click2DialEChartsMachineToJava} interface.
	   @param machineToJava instance of implementation of machine's
	   EChartsMachineToJava interface
	   @param bean specifies parameters required to establish
	   click-to-dial session e.g. first and second party addresses
	   @return interface instance to control the click-to-dial session
	   created by this method
	 */
	public static final JavaToClick2DialEChartsMachine initiate(final Click2DialEChartsMachineToJava machineToJava, 
															  final Click2DialEChartsBean bean) throws Exception {
		final SipApplicationSession appSession = EChartsSipServlet.doNonSip(bean, null, machineToJava);
		return (JavaToClick2DialEChartsMachine) JavaToEChartsMachine.getInstance(appSession);
	}

	/**
	   Initiate click-to-dial session. New session will use default
	   implementation of the machine's EChartsMachineToJava interface,
	   {@link Click2DialEChartsMachineToJavaImpl}.
	   @param party1 Address of the desired first party (String
	   representation of SIP URI)
	   @param party2 Address of the desired second party (String
	   representation of SIP URI)
	   @param timeoutSec Optional timeout in seconds for first party
	   to answer.  If no answer in the specified number of seconds,
	   then the call will abort.  A value of -1 signifies no timeout.
	   @param earlyMediaReinvite Specifies whether or not the first
	   party should receive a re-INVITE if the party returns an early
	   media response.
	   @param uid Value of X-ECHARTS-UID header in INVITE to first
		party. Default: null.
	   @return interface instance to control the click-to-dial session
	   created by this method
	 */
	public static final JavaToClick2DialEChartsMachine initiate(final String party1, final String party2,
															  final int timeoutSec, 
															  final boolean earlyMediaReinvite, 
															  final String uid) throws Exception {
		Click2DialEChartsBean bean = new Click2DialEChartsBean();
		bean.setParty1(party1);
		bean.setParty2(party2);
		bean.setTimeoutSec(timeoutSec);
		bean.setEarlyMediaReinvite(earlyMediaReinvite);
		bean.setUid(uid);
		return initiate(bean);
	}

	/**
	   Initiate click-to-dial session. Value of UID is generated
	   internally and accessible via the getUid() method.
	   @param party1 Address of the desired first party (String
	   representation of SIP URI)
	   @param party2 Address of the desired second party (String
	   representation of SIP URI)
	   @param timeoutSec Optional timeout in seconds for first party
	   to answer.  If no answer in the specified number of seconds,
	   then the call will abort. A value of -1 signifies no timeout.
	   @param earlyMediaReinvite Specifies whether or not the first
	   party should receive a re-INVITE if the party returns an early
	   media response. 
	   @return interface instance to control the click-to-dial session
	   created by this method
	 */
	public static final JavaToClick2DialEChartsMachine initiate(final String party1, final String party2, 
															  final int timeoutSec, 
															  final boolean earlyMediaReinvite) throws Exception {
		return initiate(party1, party2, timeoutSec, earlyMediaReinvite, new UniqueID().toString());
	}

	private String appSessionId = null;
	private String uid = null;
	private NonSipPort controlPort = null;

	/**
	   {@inheritDoc}

	   Sets the value of the X-ECHARTS-UID, the NonSip controlPort,
	   and the SIP app session ID used by the machine.
	 */
	protected void init(final TransitionMachine machine) throws Exception {
		Click2DialEChartsMachine c2dMachine  = (Click2DialEChartsMachine) machine;
		uid = c2dMachine.uid;
		controlPort = c2dMachine.controlPort;
		appSessionId = c2dMachine.box.getApplicationSession().getId();
	}

	/**
	   Return value of X-ECHARTS-UID header in INVITE to first party.
	   @return Value of X-ECHARTS-UID header in INVITE to first party.
	 */
	public String getUid() {
		return uid;
	}

	/**
	   Instruct MyClick2DialMachine to drop calls regardless of
	   their respective states.
	   @throws FeatureBoxException - if exception encountered sending
	   DropCalls message to the MyClick2DialMachine
	 */
	public void dropCalls() throws FeatureBoxException {
		controlPort.input(new DropCalls());
	}

	/**
	   @deprecated Use {@link
	   org.echarts.servlet.sip.JavaToSip#getSipApplicationSessionId()}
	   instead.  

	   Return SIP application session ID associated with this
	   interface instance.
	   @return SIP application session ID associated with this
	   interface instance.
	 */
	public String getApplicationSessionId() {
		return appSessionId;
	}
}
